package com.leyou.order.task;

import com.leyou.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author Eric
 * @version v1.0
 * @package com.leyou.order.task
 * @date 2019/7/15 21:38
 * @description:
 **/
@Component
@Slf4j
public class CloseOrderTask {

    @Autowired
    private RedissonClient redissonClient;


    @Autowired
    private OrderService orderService;


    /**
     * 定时任务的频率，30分钟
     */
    private static final long TASK_INTERVAL = 1800000;
    /**
     * 定时任务的锁自动释放时间。 \r\n
     * 一般只要大于各服务器的时钟飘移时长+任务执行时长即可。\r\n
     * 此处默认120秒。\r\n
     */
    private static final long TASK_LEASE_TIME = 120;
    /**
     * 订单超时的期限，1小时
     */
    private static final int OVERDUE_SECONDS = 3600;

    private static final String LOCK_KEY = "close:order:task:lock";


    @Scheduled(fixedDelay = TASK_INTERVAL)
    public void closeOrder(){

        //创建锁对象
        RLock lock = redissonClient.getLock(LOCK_KEY);


        try {
            //获取锁
            boolean boo = lock.tryLock(0, TASK_LEASE_TIME, TimeUnit.MILLISECONDS);
            if (!boo){
                // 获取锁失败，结束任务
                log.info("【清理订单任务】未能获取任务锁，结束任务。");
                return;
            }

            try {
                //计算当前时间与超时时间的差值
                Date date = DateTime.now().minusMinutes(OVERDUE_SECONDS).toDate();
                //调用清理订单的方法
                orderService.closeOverdueOrders(date);
            } finally {
                lock.unlock();
                log.info("【清理订单任务】任务执行完毕，释放锁。");
            }

        } catch (InterruptedException e) {
            log.error("【清理订单任务】获取任务锁异常，原因：{}", e.getMessage(), e);
        }


    }




}
